ICAcleanerGUI.m 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785
  1. function varargout = ICAcleanerGUI(varargin)
  2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  3. % Performs ICA decomposition and component removal. %
  4. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  5. % Copyright (C) 2013-2014, Michael J. Cheung
  6. %
  7. % This file is a part of the MEG & PLS Pipeline (MEGPLS). For more
  8. % details, see the documentation included with the software package.
  9. %
  10. % MEGPLS is free software: you can redistribute it and/or modify it under
  11. % the terms of the GNU General Public License version 2 as published by
  12. % the Free Software Foundation. This program is distributed in the hope
  13. % that it will be useful, but WITHOUT ANY WARRANTY; without even the
  14. % implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  15. % See the GNU General Public License for more details.
  16. %
  17. % You should have received a copy of the GNU General Public License along
  18. % with this program. If not, you can download the license here:
  19. % <http://www.gnu.org/licenses/old-licenses/gpl-2.0>.
  20. % Last Modified by GUIDE v2.5 31-Jul-2014 15:45:56
  21. % Begin initialization code - DO NOT EDIT
  22. gui_Singleton = 1;
  23. gui_State = struct('gui_Name', mfilename, ...
  24. 'gui_Singleton', gui_Singleton, ...
  25. 'gui_OpeningFcn', @ICAcleanerGUI_OpeningFcn, ...
  26. 'gui_OutputFcn', @ICAcleanerGUI_OutputFcn, ...
  27. 'gui_LayoutFcn', [] , ...
  28. 'gui_Callback', []);
  29. if nargin && ischar(varargin{1})
  30. gui_State.gui_Callback = str2func(varargin{1});
  31. end
  32. if nargout
  33. [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
  34. else
  35. gui_mainfcn(gui_State, varargin{:});
  36. end
  37. % End initialization code - DO NOT EDIT
  38. %--- Executes just before ICAcleanerGUI is made visible. ---%
  39. %-----------------------------------------------------%
  40. function ICAcleanerGUI_OpeningFcn(hObject, eventdata, handles, varargin)
  41. % This function has no output args, see OutputFcn.
  42. % hObject handle to figure
  43. % eventdata reserved - to be defined in a future version of MATLAB
  44. % handles structure with handles and user data (see GUIDATA)
  45. % varargin command line arguments to ICAcleanerGUI (see VARARGIN)
  46. % Choose default command line output for ICAcleanerGUI
  47. handles.output = hObject;
  48. % Make sure toolbox paths are added:
  49. [PipelineDir, ~, ~] = fileparts(which('ICAcleanerGUI.m'));
  50. handles.PipelineDir = PipelineDir;
  51. addpath(genpath(PipelineDir));
  52. rmpath([PipelineDir,'/DEFAULT_SETTINGS']); % Make sure its calling from DataID
  53. rmpath([PipelineDir,'/TEMPORARY_FIXES']); % Make sure its calling from FT toolbox
  54. CheckToolboxPaths(PipelineDir);
  55. if exist('ErrorLog_ICAcleaner.txt', 'file')
  56. system('rm ErrorLog_ICAcleaner.txt');
  57. end
  58. % Initializes variables being displayed:
  59. handles.paths.Rootpath = [];
  60. handles.paths.DataID = [];
  61. handles.name.DataID = [];
  62. handles.name.GroupID = [];
  63. handles.name.SubjID = [];
  64. handles.name.CondID = [];
  65. handles.paths.InputPreprocMEG = [];
  66. handles.paths.ICAunmixing = [];
  67. handles.paths.ICAcomponents = [];
  68. handles.paths.ICAcleanData = [];
  69. handles.gui.InpOutStatus = [];
  70. handles.gui.RmvCompStatus = [];
  71. handles.gui.SelectComps = [];
  72. handles.FTcfg = [];
  73. % Save handles:
  74. guidata(hObject, handles);
  75. % UIWAIT makes ICAcleanerGUI wait for user response (see UIRESUME)
  76. % uiwait(handles.figure1);
  77. %--- Outputs from this function are returned to the command line. ---%
  78. %--------------------------------------------------------------------%
  79. function varargout = ICAcleanerGUI_OutputFcn(hObject, eventdata, handles)
  80. % varargout cell array for returning output args (see VARARGOUT);
  81. % hObject handle to figure
  82. % eventdata reserved - to be defined in a future version of MATLAB
  83. % handles structure with handles and user data (see GUIDATA)
  84. % Get default command line output from handles structure
  85. varargout{1} = handles.output;
  86. %===================================%
  87. % FUNCTIONS FOR SELECTING ROOTPATH: %
  88. %===================================%
  89. %--- Executes on button press in ButtonSetRootpath. ---%
  90. %------------------------------------------------------%
  91. function ButtonSetRootpath_Callback(hObject, eventdata, handles)
  92. if ~isempty(handles.name.DataID)
  93. prompt = {'WARNING:'; '';
  94. 'Changing root directory will clear all current settings!'; '';
  95. 'Do you wish to continue?'};
  96. ChangeDir = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO');
  97. if strcmp(ChangeDir, 'NO')
  98. return;
  99. end
  100. end
  101. % Select and set Rootpath:
  102. SelectedPath = uigetdir;
  103. if SelectedPath == 0
  104. return % If user cancels
  105. end
  106. handles.paths.Rootpath = SelectedPath;
  107. set(handles.TextboxRootpath, 'String', handles.paths.Rootpath);
  108. % Start Waitbox:
  109. WaitBox = StartWaitBox('SETTING ROOT DIRECTORY:');
  110. % Reset DataID:
  111. handles.name.DataID = [];
  112. handles.paths.DataID = [];
  113. set(handles.TextboxDataID, 'String', 'Not Selected.');
  114. % Reset settings & GUI panels:
  115. handles = ResetGroupIDSettings (handles);
  116. handles = ResetSubjIDSettings (handles);
  117. handles = ResetCondIDSettings (handles);
  118. handles = ResetStatusSettings (handles);
  119. handles.paths.InputPreprocMEG = [];
  120. handles.paths.ICAcomponents = [];
  121. handles.paths.ICAunmixing = [];
  122. handles.paths.ICAcleanData = [];
  123. handles.gui.SelectComps = [];
  124. % Update settings & GUI panels (to enable/disable):
  125. % Note: Don't redetect or compile paths yet since no DataID yet.
  126. handles = UpdateGroupIDSettings (handles);
  127. handles = UpdateSubjIDSettings (handles);
  128. handles = UpdateCondIDSettings (handles);
  129. handles = UpdateStatusSettings (handles);
  130. % Save handles:
  131. guidata(hObject, handles);
  132. close(WaitBox);
  133. %--- Textbox to display selected Rootpath: ---%
  134. %---------------------------------------------%
  135. function TextboxRootpath_Callback(hObject, eventdata, handles)
  136. EnteredText = get(handles.TextboxRootpath, 'String');
  137. if ~isequal(EnteredText, handles.paths.Rootpath)
  138. set(handles.TextboxRootpath, 'String', handles.paths.Rootpath);
  139. msgbox('Note: Use button to change Rootpath.')
  140. end
  141. %=========================================%
  142. % FUNCTIONS FOR READING & LOADING DATAID: %
  143. %=========================================%
  144. %--- Textbox to display current DataID: ---%
  145. %------------------------------------------%
  146. function TextboxDataID_Callback(hObject, eventdata, handles)
  147. EnteredText = get(handles.TextboxDataID, 'String');
  148. if ~isequal(EnteredText, handles.name.DataID)
  149. set(handles.TextboxDataID, 'String', handles.name.DataID);
  150. msgbox('Note: Use button to change DataID.')
  151. end
  152. %--- Executes on button press in ButtonLoadDataID. ---%
  153. %-----------------------------------------------------%
  154. function ButtonLoadDataID_Callback(hObject, eventdata, handles)
  155. if isempty(handles.paths.Rootpath)
  156. msgbox('Warning: Select target directory first.', 'Warning:');
  157. return;
  158. end
  159. % Get DataID folders in current rootpath:
  160. DetectedFolders = dir([handles.paths.Rootpath,'/DataID_*']);
  161. RemoveIndex = [];
  162. for d = 1:length(DetectedFolders)
  163. if DetectedFolders(d).isdir ~= 1
  164. RemoveIndex = [RemoveIndex, d]; % Get unwanted indices
  165. end
  166. end
  167. DetectedFolders(RemoveIndex) = [];
  168. if isempty(DetectedFolders)
  169. msgbox('Error: No DataID folders detected inside target directory.', 'Error:');
  170. return;
  171. end
  172. % List DataID folders for selection:
  173. DetectedFolders = {DetectedFolders.name};
  174. SelectedIndex = listdlg('PromptString', 'Select DataID to load:',...
  175. 'ListSize', [300, 300], 'SelectionMode', 'single', 'ListString', DetectedFolders);
  176. if isempty(SelectedIndex) % If user cancels.
  177. return;
  178. end
  179. SelectedDataID = DetectedFolders{SelectedIndex};
  180. SelectedDataID(1:7) = []; % Remove "DataID_" prefix to get DataID tag.
  181. FullpathDataID = [handles.paths.Rootpath,'/DataID_',SelectedDataID];
  182. % Check or create settings .m file for ICA:
  183. if ~exist([FullpathDataID,'/SETTINGS'], 'dir')
  184. success = mkdir([FullpathDataID,'/SETTINGS']);
  185. if success == 0
  186. message = {'ERROR:'; '';
  187. 'Failed to create SETTINGS folder in selected DataID.';
  188. 'Ensure you have proper folder and file permissions.'};
  189. msgbox(message, 'ERROR:')
  190. return;
  191. end
  192. end
  193. DefaultSettingsFile = [handles.PipelineDir,'/DEFAULT_SETTINGS/Settings_ICA.m'];
  194. NewSettingsFile = [FullpathDataID,'/SETTINGS/Settings_ICA.m'];
  195. if ~exist(NewSettingsFile, 'file')
  196. status = copyfile(DefaultSettingsFile, NewSettingsFile, 'f');
  197. if status == 0
  198. message = {'ERROR:'; '';
  199. 'Failed to create ICA advanced settings .m file for selected DataID.';
  200. 'Could not copy file from [MEG]PLS "DEFAULT_SETTINGS" directory.';
  201. 'Check for proper folder and file permissions.'};
  202. msgbox(message, 'ERROR:')
  203. return;
  204. end
  205. end
  206. % Set as current DataID:
  207. handles.name.DataID = SelectedDataID;
  208. handles.paths.DataID = FullpathDataID;
  209. % Reset settings & GUI panels:
  210. handles = ResetGroupIDSettings (handles);
  211. handles = ResetSubjIDSettings (handles);
  212. handles = ResetCondIDSettings (handles);
  213. handles = ResetStatusSettings (handles);
  214. handles.paths.InputPreprocMEG = [];
  215. handles.paths.ICAcomponents = [];
  216. handles.paths.ICAunmixing = [];
  217. handles.paths.ICAcleanData = [];
  218. handles.gui.SelectComps = [];
  219. % Compile Group, Subj, and CondIDs for DataID:
  220. % Note: Also initializes Group, Subj, CondIDs.
  221. handles = DetectGroupSubjCond(handles);
  222. if isempty(handles.name.GroupID)
  223. msgbox('ERROR: No GroupID folders detected for selected DataID.')
  224. return;
  225. end
  226. % Compile paths & initialize other variables:
  227. for g = 1:length(handles.name.GroupID)
  228. for s = 1:length(handles.name.SubjID{g})
  229. for c = 1:length(handles.name.CondID)
  230. handles = CompilePaths(handles, g, s, c);
  231. try
  232. handles.gui.SelectComps{g}{s,c};
  233. handles.gui.InpOutStatus{g}{s,c}; % Didn't check initialize in UpdateStatus.
  234. handles.gui.RmvCompStatus{g}{s,c}; % - More efficient for case-by-case basis.
  235. catch
  236. handles.gui.SelectComps{g}{s,c} = [];
  237. handles.gui.InpOutStatus{g}{s,c} = [];
  238. handles.gui.RmvCompStatus{g}{s,c} = [];
  239. end
  240. end
  241. end
  242. end
  243. % Update settings & GUI panels:
  244. handles = UpdateGroupIDSettings (handles);
  245. handles = UpdateSubjIDSettings (handles);
  246. handles = UpdateCondIDSettings (handles);
  247. % Detect & update status:
  248. for g = 1:length(handles.name.GroupID)
  249. StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ...
  250. handles.name.GroupID{g}], 'Windowstyle', 'modal');
  251. for s = 1:length(handles.name.SubjID{g})
  252. waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar);
  253. for c = 1:length(handles.name.CondID)
  254. handles = DetectStatus(handles, g, s, c);
  255. end
  256. end
  257. delete(StatusWaitbar)
  258. end
  259. handles = UpdateStatusSettings(handles);
  260. % Save handles:
  261. set(handles.TextboxDataID, 'String', handles.name.DataID);
  262. guidata(hObject, handles);
  263. % Remove ErrorLog if empty:
  264. if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file')
  265. LogCheck = dir('ErrorLog_ICAcleaner.txt');
  266. if LogCheck.bytes == 0
  267. delete('ErrorLog_ICAcleaner.txt');
  268. end
  269. end
  270. %--- Executes on button press in ButtonRedetectInputIDs. --%
  271. %----------------------------------------------------------%
  272. function ButtonRedetectInputIDs_Callback(hObject, eventdata, handles)
  273. % Reset settings & GUI panels:
  274. handles = ResetGroupIDSettings (handles);
  275. handles = ResetSubjIDSettings (handles);
  276. handles = ResetCondIDSettings (handles);
  277. handles = ResetStatusSettings (handles);
  278. handles.paths.InputPreprocMEG = [];
  279. handles.paths.ICAcomponents = [];
  280. handles.paths.ICAunmixing = [];
  281. handles.paths.ICAcleanData = [];
  282. handles.gui.SelectComps = [];
  283. % Compile Group, Subj, and CondIDs for DataID:
  284. % Note: Also initializes Group, Subj, CondIDs.
  285. handles = DetectGroupSubjCond(handles);
  286. if isempty(handles.name.GroupID)
  287. msgbox('ERROR: No GroupID folders detected for selected DataID.')
  288. return;
  289. end
  290. % Compile paths & initialize other variables:
  291. for g = 1:length(handles.name.GroupID)
  292. for s = 1:length(handles.name.SubjID{g})
  293. for c = 1:length(handles.name.CondID)
  294. handles = CompilePaths(handles, g, s, c);
  295. try
  296. handles.gui.SelectComps{g}{s,c};
  297. handles.gui.InpOutStatus{g}{s,c}; % Didn't check initialize in UpdateStatus.
  298. handles.gui.RmvCompStatus{g}{s,c}; % - More efficient for case-by-case basis.
  299. catch
  300. handles.gui.SelectComps{g}{s,c} = [];
  301. handles.gui.InpOutStatus{g}{s,c} = [];
  302. handles.gui.RmvCompStatus{g}{s,c} = [];
  303. end
  304. end
  305. end
  306. end
  307. % Update settings & GUI panels:
  308. handles = UpdateGroupIDSettings (handles);
  309. handles = UpdateSubjIDSettings (handles);
  310. handles = UpdateCondIDSettings (handles);
  311. % Detect & update status:
  312. for g = 1:length(handles.name.GroupID)
  313. StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ...
  314. handles.name.GroupID{g}], 'Windowstyle', 'modal');
  315. for s = 1:length(handles.name.SubjID{g})
  316. waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar);
  317. for c = 1:length(handles.name.CondID)
  318. handles = DetectStatus(handles, g, s, c);
  319. end
  320. end
  321. delete(StatusWaitbar)
  322. end
  323. handles = UpdateStatusSettings(handles);
  324. % Save handles:
  325. guidata(hObject, handles);
  326. % Remove ErrorLog if empty:
  327. if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file')
  328. LogCheck = dir('ErrorLog_ICAcleaner.txt');
  329. if LogCheck.bytes == 0
  330. delete('ErrorLog_ICAcleaner.txt');
  331. end
  332. end
  333. %--- Detect Group, Subj, and CondID's from DataID: ---%
  334. %-----------------------------------------------------%
  335. function OutputHandles = DetectGroupSubjCond(InputHandles)
  336. handles = InputHandles;
  337. % Reset params:
  338. handles.name.GroupID = [];
  339. handles.name.SubjID = [];
  340. handles.name.CondID = [];
  341. handles.paths.InputPreprocMEG = [];
  342. handles.paths.ICAcomponents = [];
  343. handles.paths.ICAunmixing = [];
  344. handles.paths.ICAcleanData = [];
  345. % Acquire GroupID folders within DataID:
  346. DetectedGroups = dir([handles.paths.DataID,'/GroupID_*']);
  347. RemoveIndex = [];
  348. for g = 1:length(DetectedGroups)
  349. DetectedGroups(g).name(1:8) = []; % Remove "GroupID_" prefix
  350. if DetectedGroups(g).isdir ~= 1
  351. RemoveIndex = [RemoveIndex, g]; % Get unwanted indices
  352. end
  353. end
  354. DetectedGroups(RemoveIndex) = [];
  355. if isempty(DetectedGroups)
  356. handles.name.GroupID = [];
  357. else
  358. handles.name.GroupID = {DetectedGroups.name};
  359. end
  360. % Scan PreprocInput .mat files for SubjID's and CondID's:
  361. CondIDs = [];
  362. for g = 1:length(handles.name.GroupID)
  363. GroupPath = [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g}];
  364. InputMats = dir([GroupPath,'/PreprocInputMEG_*.mat']); % Find InputMats for group
  365. InputMats = {InputMats.name};
  366. SubjIDs = [];
  367. if ~isempty(InputMats)
  368. for m = 1:length(InputMats)
  369. LoadMat = load([GroupPath,'/',InputMats{m}]);
  370. SubjIDs = [SubjIDs; LoadMat.name.SubjID];
  371. CondIDs = [CondIDs; cellstr(LoadMat.name.CurrentCondID)];
  372. end
  373. else
  374. message = {['ERROR: PreprocInputMEG .mat file(s) missing for GroupID: ',...
  375. handles.name.GroupID{g}]; ''; ['As a result, some Subject & Condition IDs ' ...
  376. 'for the selected DataID may not be detected.']};
  377. msgbox(message);
  378. end
  379. handles.name.SubjID{g} = unique(SubjIDs);
  380. end
  381. handles.name.CondID = unique(CondIDs);
  382. % Set output handles:
  383. OutputHandles = handles;
  384. %--- Compiles paths for selected indices: ---%
  385. %--------------------------------------------%
  386. function OutputHandles = CompilePaths(InputHandles, g, s, c)
  387. handles = InputHandles;
  388. handles.paths.InputPreprocMEG{g}{s,c} = ...
  389. [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g},'/', ...
  390. handles.name.CondID{c},'/',handles.name.SubjID{g}{s},'_PreprocMEG.mat'];
  391. handles.paths.ICAunmixing{g}{s,c} = ...
  392. [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g},'/', ...
  393. handles.name.CondID{c},'/',handles.name.SubjID{g}{s},'_ICAunmixing.mat'];
  394. handles.paths.ICAcomponents{g}{s,c} = ...
  395. [handles.paths.DataID,'/ICAcomps/GroupID_',handles.name.GroupID{g},'/', ...
  396. handles.name.CondID{c},'/',handles.name.SubjID{g}{s},'_ICAcomponents.mat'];
  397. handles.paths.ICAcleanData{g}{s,c} = ...
  398. [handles.paths.Rootpath,'/DataID-ICAclean_',handles.name.DataID, ...
  399. '/GroupID_',handles.name.GroupID{g},'/',handles.name.CondID{c},'/', ...
  400. handles.name.SubjID{g}{s},'_PreprocMEG.mat'];
  401. % Set output handles:
  402. OutputHandles = handles;
  403. %==========================================%
  404. % FUNCTIONS FOR ADDING OR REMOVING GROUPS: %
  405. %==========================================%
  406. %--- Executes on selection change in ListboxGroupID. ---%
  407. %-------------------------------------------------------%
  408. function ListboxGroupID_Callback(hObject, eventdata, handles)
  409. if isempty(handles.name.GroupID)
  410. return;
  411. end
  412. handles = UpdateSubjIDSettings (handles);
  413. handles = UpdateStatusSettings (handles);
  414. guidata(hObject, handles);
  415. %--- Executes on button press in ButtonRmvGroupID. ---%
  416. %-----------------------------------------------------%
  417. function ButtonRmvGroupID_Callback(hObject, eventdata, handles)
  418. if isempty(handles.name.GroupID)
  419. return;
  420. end
  421. if length(handles.name.GroupID) <= 1
  422. msgbox('Note: Must have at least 1 GroupID.', 'Error:');
  423. return;
  424. end
  425. SelectedIndex = get(handles.ListboxGroupID, 'Value');
  426. handles.name.GroupID(SelectedIndex) = [];
  427. if ~isempty(handles.name.SubjID)
  428. handles.name.SubjID(SelectedIndex) = [];
  429. end
  430. if ~isempty(handles.paths.InputPreprocMEG)
  431. handles.paths.InputPreprocMEG (SelectedIndex) = [];
  432. handles.paths.ICAunmixing (SelectedIndex) = [];
  433. handles.paths.ICAcomponents (SelectedIndex) = [];
  434. handles.paths.ICAcleanData (SelectedIndex) = [];
  435. end
  436. if ~isempty(handles.gui.SelectComps)
  437. handles.gui.SelectComps(SelectedIndex) = [];
  438. end
  439. if ~isempty(handles.gui.InpOutStatus)
  440. handles.gui.InpOutStatus(SelectedIndex) = [];
  441. end
  442. if ~isempty(handles.gui.RmvCompStatus)
  443. handles.gui.RmvCompStatus(SelectedIndex) = [];
  444. end
  445. % Update settings & GUI:
  446. handles = UpdateGroupIDSettings (handles);
  447. handles = UpdateSubjIDSettings (handles);
  448. handles = UpdateStatusSettings (handles);
  449. % Save handles:
  450. guidata(hObject, handles);
  451. %--- Update GroupID settings & GUI panel: ---%
  452. %--------------------------------------------%
  453. function OutputHandles = UpdateGroupIDSettings(InputHandles)
  454. handles = InputHandles;
  455. % Update listbox:
  456. set(handles.ListboxGroupID, 'String', handles.name.GroupID);
  457. CurrentIndex = get(handles.ListboxGroupID, 'Value');
  458. MaxGroupIndex = length(handles.name.GroupID);
  459. if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxGroupIndex
  460. set(handles.ListboxGroupID, 'Value', MaxGroupIndex);
  461. end
  462. % Set output handles:
  463. OutputHandles = handles;
  464. %--- Reset GroupID settings & GUI panel: ---%
  465. %-------------------------------------------%
  466. function OutputHandles = ResetGroupIDSettings(InputHandles)
  467. handles = InputHandles;
  468. handles.name.GroupID = [];
  469. set(handles.ListboxGroupID, 'String', []);
  470. set(handles.ListboxGroupID, 'Value', 1);
  471. % Set output handles:
  472. OutputHandles = handles;
  473. %============================================%
  474. % FUNCTIONS FOR ADDING OR REMOVING SUBJECTS: %
  475. %============================================%
  476. %--- Executes on selection change in ListboxSubjID. ---%
  477. %------------------------------------------------------%
  478. function ListboxSubjID_Callback(hObject, eventdata, handles)
  479. if isempty(handles.name.SubjID)
  480. return;
  481. end
  482. GroupIndex = get(handles.ListboxGroupID, 'Value');
  483. if isempty(handles.name.SubjID{GroupIndex})
  484. return;
  485. end
  486. SubjIndex = get(handles.ListboxSubjID, 'Value');
  487. set(handles.ListboxInpOutStatus, 'Value', SubjIndex);
  488. set(handles.ListboxRmvCompStatus, 'Value', SubjIndex);
  489. %--- User enters subject to add into this textbox. ---%
  490. %-----------------------------------------------------%
  491. function TextboxSubjID_Callback(hObject, eventdata, handles)
  492. keypress = get(gcf,'CurrentCharacter');
  493. if isequal(keypress, char(13))
  494. ButtonAddSubjID_Callback(hObject, eventdata, handles);
  495. end
  496. %--- Executes on button press in ButtonAddSubjID. ---%
  497. %----------------------------------------------------%
  498. function ButtonAddSubjID_Callback(hObject, eventdata, handles)
  499. if isempty(handles.name.DataID)
  500. msgbox('Warning: Load DataID first.', 'Warning:');
  501. return;
  502. end
  503. if isempty(handles.name.GroupID)
  504. msgbox('Error: No GroupIDs specified.', 'Error:');
  505. return;
  506. end
  507. % Read entered SubjID:
  508. InputSubjID = get(handles.TextboxSubjID, 'String');
  509. InputSubjID = deblank(InputSubjID);
  510. InputSubjID = regexprep(InputSubjID, '\s+', '_');
  511. InputSubjID = cellstr(InputSubjID);
  512. if isempty(InputSubjID{1})
  513. return;
  514. end
  515. GroupIndex = get(handles.ListboxGroupID, 'Value');
  516. if ismember(InputSubjID{1}, handles.name.SubjID{GroupIndex})
  517. return; % If SubjID already added
  518. end
  519. % Add SubjID for group & initialize:
  520. handles.name.SubjID{GroupIndex} = [handles.name.SubjID{GroupIndex}; InputSubjID];
  521. NewSubjIndex = length(handles.name.SubjID{GroupIndex});
  522. for c = 1:length(handles.name.CondID)
  523. handles.gui.SelectComps{GroupIndex}{NewSubjIndex,c} = [];
  524. handles = CompilePaths(handles, GroupIndex, NewSubjIndex, c);
  525. handles = DetectStatus(handles, GroupIndex, NewSubjIndex, c);
  526. end
  527. % Update settings & GUI:
  528. handles = UpdateSubjIDSettings (handles);
  529. handles = UpdateStatusSettings (handles);
  530. % Save handles:
  531. set(handles.ListboxSubjID, 'Value', NewSubjIndex);
  532. if ~isempty(handles.gui.InpOutStatus)
  533. set(handles.ListboxInpOutStatus, 'Value', NewSubjIndex);
  534. end
  535. if ~isempty(handles.gui.RmvCompStatus)
  536. set(handles.ListboxRmvCompStatus, 'Value', NewSubjIndex);
  537. end
  538. guidata(hObject, handles);
  539. %--- Executes on button press in ButtonRmvSubjID. ---%
  540. %----------------------------------------------------%
  541. function ButtonRmvSubjID_Callback(hObject, eventdata, handles)
  542. if isempty(handles.name.SubjID)
  543. return;
  544. end
  545. GroupIndex = get(handles.ListboxGroupID, 'Value');
  546. SubjIndex = get(handles.ListboxSubjID, 'Value');
  547. if isempty(handles.name.SubjID{GroupIndex})
  548. return;
  549. end
  550. handles.name.SubjID{GroupIndex}(SubjIndex) = [];
  551. if ~isempty(handles.paths.InputPreprocMEG)
  552. handles.paths.InputPreprocMEG {GroupIndex}(SubjIndex,:) = [];
  553. handles.paths.ICAunmixing {GroupIndex}(SubjIndex,:) = [];
  554. handles.paths.ICAcomponents {GroupIndex}(SubjIndex,:) = [];
  555. handles.paths.ICAcleanData {GroupIndex}(SubjIndex,:) = [];
  556. end
  557. if ~isempty(handles.gui.SelectComps)
  558. handles.gui.SelectComps{GroupIndex}(SubjIndex,:) = [];
  559. end
  560. if ~isempty(handles.gui.InpOutStatus)
  561. handles.gui.InpOutStatus{GroupIndex}(SubjIndex,:) = [];
  562. end
  563. if ~isempty(handles.gui.RmvCompStatus)
  564. handles.gui.RmvCompStatus{GroupIndex}(SubjIndex,:) = [];
  565. end
  566. % Update settings & GUI:
  567. handles = UpdateSubjIDSettings (handles);
  568. handles = UpdateStatusSettings (handles);
  569. % Save handles:
  570. guidata(hObject, handles);
  571. %--- Update SubjID settings & GUI panel: ---%
  572. %-------------------------------------------%
  573. function OutputHandles = UpdateSubjIDSettings(InputHandles)
  574. handles = InputHandles;
  575. % Update listbox:
  576. GroupIndex = get(handles.ListboxGroupID, 'Value');
  577. if isempty(handles.name.SubjID)
  578. set(handles.ListboxSubjID, 'String', []);
  579. MaxSubjIndex = 0;
  580. else
  581. set(handles.ListboxSubjID, 'String', handles.name.SubjID{GroupIndex});
  582. MaxSubjIndex = length(handles.name.SubjID{GroupIndex});
  583. end
  584. SubjIndex = get(handles.ListboxSubjID, 'Value');
  585. if isempty(SubjIndex) || SubjIndex == 0 || SubjIndex > MaxSubjIndex
  586. set(handles.ListboxSubjID, 'Value', MaxSubjIndex);
  587. if ~isempty(handles.gui.InpOutStatus)
  588. set(handles.ListboxInpOutStatus, 'Value', MaxSubjIndex);
  589. end
  590. if ~isempty(handles.gui.RmvCompStatus)
  591. set(handles.ListboxRmvCompStatus, 'Value', MaxSubjIndex);
  592. end
  593. end
  594. % Set output handles:
  595. OutputHandles = handles;
  596. %--- Reset SubjID settings & GUI panel: ---%
  597. %------------------------------------------%
  598. function OutputHandles = ResetSubjIDSettings(InputHandles)
  599. handles = InputHandles;
  600. handles.name.SubjID = [];
  601. set(handles.ListboxSubjID, 'String', []);
  602. set(handles.ListboxSubjID, 'Value', 1);
  603. % Set output handles:
  604. OutputHandles = handles;
  605. %==============================================%
  606. % FUNCTIONS FOR ADDING OR REMOVING CONDITIONS: %
  607. %==============================================%
  608. %--- Executes on selection change in ListboxCondID. ---%
  609. %------------------------------------------------------%
  610. function ListboxCondID_Callback(hObject, eventdata, handles)
  611. if isempty(handles.name.CondID)
  612. return;
  613. end
  614. handles = UpdateStatusSettings(handles);
  615. guidata(hObject, handles);
  616. %--- User enters condition to add into this textbox. ---%
  617. %-------------------------------------------------------%
  618. function TextboxCondID_Callback(hObject, eventdata, handles)
  619. keypress = get(gcf,'CurrentCharacter');
  620. if isequal(keypress, char(13))
  621. ButtonAddCondID_Callback(hObject, eventdata, handles);
  622. end
  623. %--- Executes on button press in ButtonAddCondID. ---%
  624. %----------------------------------------------------%
  625. function ButtonAddCondID_Callback(hObject, eventdata, handles)
  626. if isempty(handles.name.DataID)
  627. msgbox('Warning: Load DataID first.', 'Warning:');
  628. return;
  629. end
  630. if isempty(handles.name.GroupID)
  631. msgbox('Error: No GroupIDs specified.', 'Error:');
  632. return;
  633. end
  634. % Read entered CondID:
  635. InputCondID = get(handles.TextboxCondID, 'String');
  636. InputCondID = deblank(InputCondID);
  637. InputCondID = regexprep(InputCondID, '\s+', '_');
  638. InputCondID = cellstr(InputCondID);
  639. if isempty(InputCondID{1})
  640. return;
  641. end
  642. if ismember(InputCondID{1}, handles.name.CondID)
  643. return; % If CondID already added
  644. end
  645. % Add CondID and initialize:
  646. handles.name.CondID = [handles.name.CondID; InputCondID];
  647. NewCondIndex = length(handles.name.CondID);
  648. for g = 1:length(handles.name.GroupID)
  649. if isempty(handles.name.SubjID)
  650. continue;
  651. end
  652. for s = 1:length(handles.name.SubjID{g})
  653. handles.gui.SelectComps{g}{s, NewCondIndex} = [];
  654. handles = CompilePaths(handles, g, s, NewCondIndex);
  655. handles = DetectStatus(handles, g, s, NewCondIndex);
  656. end
  657. end
  658. set(handles.ListboxCondID, 'Value', NewCondIndex);
  659. % Update settings & GUI:
  660. handles = UpdateCondIDSettings (handles);
  661. handles = UpdateStatusSettings (handles);
  662. % Save handles:
  663. guidata(hObject, handles);
  664. %--- Executes on button press in ButtonRmvCondID. ---%
  665. %----------------------------------------------------%
  666. function ButtonRmvCondID_Callback(hObject, eventdata, handles)
  667. if isempty(handles.name.CondID)
  668. return;
  669. end
  670. SelectedIndex = get(handles.ListboxCondID, 'Value');
  671. handles.name.CondID(SelectedIndex) = [];
  672. for g = 1:length(handles.name.GroupID)
  673. if ~isempty(handles.paths.InputPreprocMEG)
  674. handles.paths.InputPreprocMEG {g}(:,SelectedIndex) = [];
  675. handles.paths.ICAunmixing {g}(:,SelectedIndex) = [];
  676. handles.paths.ICAcomponents {g}(:,SelectedIndex) = [];
  677. handles.paths.ICAcleanData {g}(:,SelectedIndex) = [];
  678. end
  679. if ~isempty(handles.gui.SelectComps)
  680. handles.gui.SelectComps{g}(:,SelectedIndex) = [];
  681. end
  682. if ~isempty(handles.gui.InpOutStatus)
  683. handles.gui.InpOutStatus{g}(:,SelectedIndex) = [];
  684. end
  685. if ~isempty(handles.gui.RmvCompStatus)
  686. handles.gui.RmvCompStatus{g}(:,SelectedIndex) = [];
  687. end
  688. end
  689. % Update settings & GUI:
  690. handles = UpdateCondIDSettings (handles);
  691. handles = UpdateStatusSettings (handles);
  692. % Save handles:
  693. guidata(hObject, handles);
  694. %--- Updates CondID settings & GUI panel: ---%
  695. %--------------------------------------------%
  696. function OutputHandles = UpdateCondIDSettings(InputHandles)
  697. handles = InputHandles;
  698. % Update listbox:
  699. set(handles.ListboxCondID, 'String', handles.name.CondID);
  700. CurrentIndex = get(handles.ListboxCondID, 'Value');
  701. MaxCondIndex = length(handles.name.CondID);
  702. if isempty(CurrentIndex) || CurrentIndex == 0 || CurrentIndex > MaxCondIndex
  703. set(handles.ListboxCondID, 'Value', MaxCondIndex);
  704. end
  705. % Set output handles:
  706. OutputHandles = handles;
  707. %--- Reset CondID settings & GUI panel: ---%
  708. %------------------------------------------%
  709. function OutputHandles = ResetCondIDSettings(InputHandles)
  710. handles = InputHandles;
  711. handles.name.CondID = [];
  712. set(handles.ListboxCondID, 'String', []);
  713. set(handles.ListboxCondID, 'Value', 1);
  714. % Set output handles:
  715. OutputHandles = handles;
  716. %===============================%
  717. % FUNCTIONS FOR STATUS UPDATES: %
  718. %===============================%
  719. %--- Executes on selection change in ListboxInpOutStatus. ---%
  720. %------------------------------------------------------------%
  721. function ListboxInpOutStatus_Callback(hObject, eventdata, handles)
  722. if isempty(handles.gui.InpOutStatus)
  723. return;
  724. end
  725. if ~isempty(handles.name.GroupID) % In case where SubjID exist but CondID missing
  726. GroupIndex = get(handles.ListboxGroupID, 'Value');
  727. if isempty(handles.gui.InpOutStatus{GroupIndex})
  728. return;
  729. end
  730. end
  731. SelectedIndex = get(handles.ListboxInpOutStatus, 'Value');
  732. set(handles.ListboxSubjID, 'Value', SelectedIndex);
  733. set(handles.ListboxRmvCompStatus, 'Value', SelectedIndex);
  734. %--- Executes on selection change in ListboxRmvCompStatus. ---%
  735. %-------------------------------------------------------------%
  736. function ListboxRmvCompStatus_Callback(hObject, eventdata, handles)
  737. if isempty(handles.gui.RmvCompStatus)
  738. return;
  739. end
  740. if ~isempty(handles.name.GroupID)
  741. GroupIndex = get(handles.ListboxGroupID, 'Value');
  742. if isempty(handles.gui.RmvCompStatus{GroupIndex})
  743. return;
  744. end
  745. end
  746. SelectedIndex = get(handles.ListboxRmvCompStatus, 'Value');
  747. set(handles.ListboxSubjID, 'Value', SelectedIndex);
  748. set(handles.ListboxInpOutStatus, 'Value', SelectedIndex);
  749. %--- Executes on button press in ButtonRefreshStatus. ---%
  750. %--------------------------------------------------------%
  751. function ButtonRefreshStatus_Callback(hObject, eventdata, handles)
  752. % Detect & update status:
  753. for g = 1:length(handles.name.GroupID)
  754. StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ...
  755. handles.name.GroupID{g}], 'Windowstyle', 'modal');
  756. for s = 1:length(handles.name.SubjID{g})
  757. waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar);
  758. for c = 1:length(handles.name.CondID)
  759. handles = DetectStatus(handles, g, s, c);
  760. end
  761. end
  762. delete(StatusWaitbar)
  763. end
  764. handles = UpdateStatusSettings(handles);
  765. % Save handles:
  766. guidata(hObject, handles);
  767. %--- Executes on button press in CheckboxShowOutputStatus. ---%
  768. %-------------------------------------------------------------%
  769. function CheckboxShowOutputStatus_Callback(hObject, eventdata, handles)
  770. % Detect & update status:
  771. for g = 1:length(handles.name.GroupID)
  772. StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ...
  773. handles.name.GroupID{g}], 'Windowstyle', 'modal');
  774. for s = 1:length(handles.name.SubjID{g})
  775. waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar);
  776. for c = 1:length(handles.name.CondID)
  777. handles = DetectStatus(handles, g, s, c);
  778. end
  779. end
  780. delete(StatusWaitbar)
  781. end
  782. handles = UpdateStatusSettings(handles);
  783. % Save handles:
  784. guidata(hObject, handles);
  785. %--- Detect input file status: ---%
  786. %---------------------------------%
  787. function OutputHandles = DetectStatus(InputHandles, g, s, c)
  788. handles = InputHandles;
  789. InputPreprocMEG = handles.paths.InputPreprocMEG{g}{s,c};
  790. ICAunmixing = handles.paths.ICAunmixing{g}{s,c};
  791. ICAcomponents = handles.paths.ICAcomponents{g}{s,c};
  792. ICAcleanData = handles.paths.ICAcleanData{g}{s,c};
  793. % Get input or output file status:
  794. if ~exist(ICAcleanData, 'file') || get(handles.CheckboxShowOutputStatus, 'Value') == 0
  795. if exist(InputPreprocMEG, 'file')
  796. if exist(ICAcomponents, 'file')
  797. StatusMsg = 'Input PreprocMEG found (ICA components found).';
  798. elseif exist(ICAunmixing, 'file')
  799. StatusMsg = 'Input PreprocMEG found (Unmixing data found; Run ICA to apply).';
  800. else
  801. StatusMsg = 'Input PreprocMEG found (Ready for ICA).';
  802. end
  803. else
  804. StatusMsg = 'Error: Input PreprocMEG file missing.';
  805. end
  806. else
  807. LoadCleanData = LoadFTmat(ICAcleanData, 'ICAcleaner');
  808. if isempty(LoadCleanData)
  809. StatusMsg = 'Error: Output file contains errors. See ErrorLog.';
  810. else
  811. if isfield(LoadCleanData, 'ICAcompRemoved')
  812. if isempty(LoadCleanData.ICAcompRemoved)
  813. StatusMsg = 'ICA cleaned file found: No components removed.';
  814. else
  815. NumCompRmv = num2str(length(LoadCleanData.ICAcompRemoved));
  816. StrCompRmv = regexprep(num2str(LoadCleanData.ICAcompRemoved), '\s+', ', ');
  817. StatusMsg = ['ICA cleaned file found: ', ...
  818. NumCompRmv,' comp. removed (',StrCompRmv,')'];
  819. end
  820. else
  821. StatusMsg = 'Error: Output file is missing ICAcompRemoved field.';
  822. end
  823. end
  824. end
  825. handles.gui.InpOutStatus{g}{s,c} = StatusMsg;
  826. % Get ICA component status:
  827. if ~exist(ICAunmixing, 'file')
  828. RmvCompStatus = 'Missing ICA decomposition files (Run ICA).';
  829. else
  830. if isempty(handles.gui.SelectComps{g}{s,c})
  831. RmvCompStatus = 'Select unwanted components.';
  832. else
  833. StrCompRmv = regexprep(num2str(handles.gui.SelectComps{g}{s,c}), '\s+', ', ');
  834. RmvCompStatus = ['Rejecting components: [',StrCompRmv,']'];
  835. end
  836. end
  837. handles.gui.RmvCompStatus{g}{s,c} = RmvCompStatus;
  838. % Set output handles:
  839. OutputHandles = handles;
  840. %--- Update status settings & GUI panel: ---%
  841. %-------------------------------------------%
  842. function OutputHandles = UpdateStatusSettings(InputHandles)
  843. handles = InputHandles;
  844. % Make sure cells initialized:
  845. for g = 1:length(handles.name.GroupID)
  846. for s = 1:length(handles.name.SubjID{g})
  847. for c = 1:length(handles.name.CondID)
  848. try
  849. handles.gui.SelectComps{g}{s,c};
  850. handles.gui.InpOutStatus{g}{s,c}; % Check just in case.
  851. handles.gui.RmvCompStatus{g}{s,c}; % - ** If too much delay, can rmv.
  852. catch
  853. handles.gui.SelectComps{g}{s,c} = [];
  854. handles.gui.InpOutStatus{g}{s,c} = [];
  855. handles.gui.RmvCompStatus{g}{s,c} = [];
  856. end
  857. end
  858. end
  859. end
  860. % Update listbox:
  861. GroupIndex = get(handles.ListboxGroupID, 'Value');
  862. SubjIndex = get(handles.ListboxSubjID, 'Value');
  863. CondIndex = get(handles.ListboxCondID, 'Value');
  864. if isempty(handles.gui.InpOutStatus) || isempty(handles.gui.InpOutStatus{GroupIndex})
  865. set(handles.ListboxInpOutStatus, 'String', []);
  866. set(handles.ListboxInpOutStatus, 'Value', 1);
  867. else
  868. set(handles.ListboxInpOutStatus, 'String', ...
  869. handles.gui.InpOutStatus{GroupIndex}(:,CondIndex));
  870. if get(handles.ListboxInpOutStatus, 'Value') ~= SubjIndex
  871. set(handles.ListboxInpOutStatus, 'Value', SubjIndex);
  872. end
  873. end
  874. if isempty(handles.gui.RmvCompStatus) || isempty(handles.gui.RmvCompStatus{GroupIndex})
  875. set(handles.ListboxRmvCompStatus, 'String', []);
  876. set(handles.ListboxRmvCompStatus, 'Value', 1);
  877. else
  878. set(handles.ListboxRmvCompStatus, 'String', ...
  879. handles.gui.RmvCompStatus{GroupIndex}(:,CondIndex));
  880. if get(handles.ListboxRmvCompStatus, 'Value') ~= SubjIndex
  881. set(handles.ListboxRmvCompStatus, 'Value', SubjIndex)
  882. end
  883. end
  884. % Set output handles:
  885. OutputHandles = handles;
  886. %--- Reset status settings & GUI panel: ---%
  887. %------------------------------------------%
  888. function OutputHandles = ResetStatusSettings(InputHandles)
  889. handles = InputHandles;
  890. % Reset:
  891. handles.gui.InpOutStatus = [];
  892. handles.gui.RmvCompStatus = [];
  893. % Reinitialize:
  894. for g = 1:length(handles.name.GroupID)
  895. for s = 1:length(handles.name.SubjID{g})
  896. for c = 1:length(handles.name.CondID)
  897. handles.gui.InpOutStatus{g}{s,c} = [];
  898. handles.gui.RmvCompStatus{g}{s,c} = [];
  899. end
  900. end
  901. end
  902. % Reset GUI listboxes:
  903. set(handles.ListboxInpOutStatus, 'String', []);
  904. set(handles.ListboxRmvCompStatus, 'String', []);
  905. set(handles.ListboxInpOutStatus, 'Value', 1);
  906. set(handles.ListboxRmvCompStatus, 'Value', 1);
  907. % Set output handles:
  908. OutputHandles = handles;
  909. %=======================%
  910. % FUNCTIONS TO RUN ICA: %
  911. %=======================%
  912. %--- Executes on button press in ButtonShowInstructions. ---%
  913. %-----------------------------------------------------------%
  914. function ButtonShowInstructions_Callback(hObject, eventdata, handles)
  915. Instructions = {'-------------'; 'INSTRUCTIONS:'; '-------------'; '';
  916. 'LOADING INPUT DATA:';
  917. ' 1) Load the DataID that you wish to apply ICA cleaning to.';
  918. ' 2) The DataID will be scanned for Group, Subject & Condition IDs.';
  919. ' 3) Use the "-" keys to exclude datasets from the ICA analysis.';
  920. ' 4) Use the "+" keys to add missing Subject or Condition IDs.';
  921. '';
  922. ' NOTE: To restore the full list of Group, Subject, and Condition IDs';
  923. ' found within the DataID, push the "Redetect Input" button.';
  924. ''; '';
  925. 'RUN ICA DECOMPOSITION:';
  926. ' 1) Change ICA settings as needed using the "ICA Adv. Settings" button.';
  927. ' 2) Once desired data is selected (see above), push "Run ICA" button.';
  928. ''; '';
  929. 'VIEWING ICA COMPONENT RESULTS:';
  930. ' - Select the Group, Subj & Cond ID you wish to view from the lists.';
  931. ' - Push the "View Components" button to open the component browser.';
  932. ' This browser displays topoplots & time-courses for each component.';
  933. ' Note: Time-courses display concatenated trial data for components.'; '';
  934. ' - Using the Data Browser:';
  935. ' a) To change components viewed, use the ">" & "<" keys for "Channels".';
  936. ' b) To scroll across time-course, use the ">" & "<" keys for "Segment".';
  937. ' c) To change amp. scaling, use the ">" & "<" keys under "Vertical".';
  938. ' d) To change time scaling, use the ">" & "<" keys under "Horizontal".';
  939. ''; '';
  940. 'REJECTING COMPONENTS:';
  941. ' 1) Select the Group, Subj & Cond ID you wish to view from the lists.';
  942. ' 2) Identify artifact components for the selected dataset (see above).';
  943. ' 3) Push the "Select Components" button and select artifact components.';
  944. ' 4) Repeat Steps 1-3 for each dataset.';
  945. ' 5) When ready, push the "Rmv Comp. & Clean Data" button.'; ''; ''};
  946. msgbox(Instructions, 'INSTRUCTIONS:')
  947. %--- Executes on button press in ButtonAdvSettings. ---%
  948. %------------------------------------------------------%
  949. function ButtonAdvSettings_Callback(hObject, eventdata, handles)
  950. if isempty(handles.paths.Rootpath)
  951. msgbox('Warning: Select target directory first.', 'Warning:');
  952. return;
  953. end
  954. if isempty(handles.name.DataID)
  955. msgbox('Warning: Load DataID first.', 'Warning:');
  956. return;
  957. end
  958. open([handles.paths.DataID,'/SETTINGS/Settings_ICA.m']);
  959. %--- Executes on button press in ButtonRunICA. ---%
  960. %-------------------------------------------------%
  961. function ButtonRunICA_Callback(hObject, eventdata, handles)
  962. if isempty(handles.name.DataID)
  963. msgbox('Warning: Load DataID first.', 'Warning:');
  964. return;
  965. end
  966. if isempty(handles.name.GroupID)
  967. msgbox('Error: No GroupIDs specified.', 'Error:');
  968. return;
  969. end
  970. if isempty(handles.name.SubjID)
  971. msgbox('Error: No SubjIDs specified.', 'Error:');
  972. return;
  973. else
  974. for g = 1:length(handles.name.GroupID)
  975. if isempty(handles.name.SubjID{g})
  976. msgbox('Error: Not all Groups have SubjIDs added.', 'Error:')
  977. return;
  978. end
  979. end
  980. end
  981. if isempty(handles.name.CondID)
  982. msgbox('Error: No CondIDs specified.', 'Error:');
  983. return;
  984. end
  985. % Load required parameters:
  986. InputParams.name = handles.name;
  987. InputParams.paths.InputPreprocMEG = handles.paths.InputPreprocMEG;
  988. InputParams.paths.ICAunmixing = handles.paths.ICAunmixing;
  989. InputParams.paths.ICAcomponents = handles.paths.ICAcomponents;
  990. FTcfg.ResampleICA = [];
  991. FTcfg.ICA = [];
  992. CurrentDir = pwd;
  993. cd([handles.paths.DataID,'/SETTINGS/']);
  994. [FTcfg.ResampleICA, FTcfg.ICA] = Settings_ICA;
  995. cd(CurrentDir);
  996. % Check for previously computed unmixing matrices:
  997. ExistingFiles = 0;
  998. for g = 1:length(handles.name.GroupID)
  999. for s = 1:length(handles.name.SubjID{g})
  1000. for c = 1:length(handles.name.CondID)
  1001. if exist(handles.paths.ICAunmixing{g}{s,c}, 'file')
  1002. ExistingFiles = 1;
  1003. end
  1004. end
  1005. end
  1006. end
  1007. if ExistingFiles == 1
  1008. prompt = {'CONFIRM: ICA unmixing matrices from previous ICA runs detected.'; '';
  1009. 'To APPLY existing unmixing data to their respective datasets, push APPLY.';
  1010. 'Note: Choose this option to save time if ICA settings have NOT changed.'; '';
  1011. 'To REDO & OVERWRITE the ICA decomposition for each dataset, push REDO.';
  1012. 'Note: Choose this option if you wish to re-run ICA with new settings.'};
  1013. RunChoice = questdlg(prompt, 'NOTE:', 'APPLY', 'REDO', 'Cancel', 'Cancel');
  1014. else
  1015. RunChoice = 'REDO';
  1016. end
  1017. if strcmp(RunChoice, 'Cancel')
  1018. return;
  1019. end
  1020. CheckOpenPCT
  1021. % Run ICA decomposition:
  1022. disp('PERFORMING ICA DECOMPOSITION:')
  1023. MEGpipeline_RunICA(FTcfg, InputParams, RunChoice);
  1024. % Detect & update status:
  1025. for g = 1:length(handles.name.GroupID)
  1026. StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ...
  1027. handles.name.GroupID{g}], 'Windowstyle', 'modal');
  1028. for s = 1:length(handles.name.SubjID{g})
  1029. waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar);
  1030. for c = 1:length(handles.name.CondID)
  1031. handles = DetectStatus(handles, g, s, c);
  1032. end
  1033. end
  1034. delete(StatusWaitbar);
  1035. end
  1036. handles = UpdateStatusSettings(handles);
  1037. % Save handles:
  1038. guidata(hObject, handles);
  1039. % Remove ErrorLog if empty:
  1040. if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file')
  1041. LogCheck = dir('ErrorLog_ICAcleaner.txt');
  1042. if LogCheck.bytes == 0
  1043. delete('ErrorLog_ICAcleaner.txt');
  1044. end
  1045. end
  1046. %========================================%
  1047. % FUNCTIONS TO VIEW & REJECT COMPONENTS: %
  1048. %========================================%
  1049. %--- Executes on button press in ButtonViewComponents. ---%
  1050. %---------------------------------------------------------%
  1051. function ButtonViewComponents_Callback(hObject, eventdata, handles)
  1052. if isempty(handles.name.DataID)
  1053. msgbox('Warning: Load DataID first.', 'Warning:');
  1054. return;
  1055. end
  1056. if isempty(handles.name.GroupID)
  1057. msgbox('Error: No GroupIDs specified.', 'Error:');
  1058. return;
  1059. end
  1060. if isempty(handles.name.SubjID)
  1061. msgbox('Error: No SubjIDs specified.', 'Error:');
  1062. return;
  1063. else
  1064. g = get(handles.ListboxGroupID, 'Value');
  1065. if isempty(handles.name.SubjID{g})
  1066. msgbox('Error: No SubjIDs added for selected Group.', 'Error:')
  1067. return;
  1068. end
  1069. end
  1070. if isempty(handles.name.CondID)
  1071. msgbox('Error: No CondIDs specified.', 'Error:');
  1072. return;
  1073. end
  1074. % Load component file for dataset:
  1075. % Note: Didn't read from disk (need sensor layout).
  1076. g = get(handles.ListboxGroupID, 'Value');
  1077. s = get(handles.ListboxSubjID, 'Value');
  1078. c = get(handles.ListboxCondID, 'Value');
  1079. if ~exist(handles.paths.ICAcomponents{g}{s,c}, 'file')
  1080. msgbox('Error: ICA component file missing for selected dataset.')
  1081. return;
  1082. end
  1083. LoadComp = LoadFTmat(handles.paths.ICAcomponents{g}{s,c}, 'ICAcleaner');
  1084. if isempty(LoadComp)
  1085. msgbox('Error: ICA component file found, but contains errors. See ErrorLog.')
  1086. return;
  1087. end
  1088. % Open databrowser:
  1089. cfgview.viewmode = 'component';
  1090. cfgview.channel = [1:10]; % View 10 components at a time.
  1091. cfgview.compscale = 'local'; % Keep this local for proper scaling.
  1092. cfgview.zlim = 'maxmin';
  1093. cfgview.ylim = 'maxmin';
  1094. cfgview.continuous = 'yes'; % Concatenate trials for viewing.
  1095. cfgview.blocksize = 20;
  1096. ft_databrowser(cfgview, LoadComp);
  1097. % Also open topoplots for first 30 components: ** Removed for now, takes too long
  1098. % figure; % Open new figure.
  1099. % cfgtopo.component = [1:20];
  1100. % cfgtopo.comment = 'no';
  1101. % ft_topoplotIC(cfgtopo, LoadComp);
  1102. % Save handles:
  1103. guidata(hObject, handles);
  1104. %--- Executes on button press in ButtonSelectComponents. ---%
  1105. %------------------------------------------------------------
  1106. function ButtonSelectComponents_Callback(hObject, eventdata, handles)
  1107. if isempty(handles.name.DataID)
  1108. msgbox('Warning: Load DataID first.', 'Warning:');
  1109. return;
  1110. end
  1111. if isempty(handles.name.GroupID)
  1112. msgbox('Error: No GroupIDs specified.', 'Error:');
  1113. return;
  1114. end
  1115. if isempty(handles.name.SubjID)
  1116. msgbox('Error: No SubjIDs specified.', 'Error:');
  1117. return;
  1118. else
  1119. g = get(handles.ListboxGroupID, 'Value');
  1120. if isempty(handles.name.SubjID{g})
  1121. msgbox('Error: No SubjIDs added for selected Group.', 'Error:')
  1122. return;
  1123. end
  1124. end
  1125. if isempty(handles.name.CondID)
  1126. msgbox('Error: No CondIDs specified.', 'Error:');
  1127. return;
  1128. end
  1129. % Load unmixing info for dataset:
  1130. % Note: Only need unmixing info for component rejection.
  1131. % Allows user to apply previous ICA cleaning to a dataset.
  1132. g = get(handles.ListboxGroupID, 'Value');
  1133. s = get(handles.ListboxSubjID, 'Value');
  1134. c = get(handles.ListboxCondID, 'Value');
  1135. if ~exist(handles.paths.ICAunmixing{g}{s,c}, 'file')
  1136. message = {'ERROR:';
  1137. 'ICA unmixing info is missing for the selected dataset.';
  1138. 'Run ICA for the dataset to generate required files.'};
  1139. msgbox(message);
  1140. return;
  1141. end
  1142. LoadUnmix = LoadFTmat(handles.paths.ICAunmixing{g}{s,c}, 'ICAcleaner');
  1143. if isempty(LoadUnmix)
  1144. msgbox('Error: ICA unmixing file contains errors. See ErrorLog.')
  1145. return;
  1146. end
  1147. % Open selection list for available components:
  1148. SelectedComps = listdlg('PromptString', 'Select ICA components to REJECT:', ...
  1149. 'ListSize', [300, 300], 'SelectionMode', 'multiple', 'ListString', LoadUnmix.label);
  1150. handles.gui.SelectComps{g}{s,c} = SelectedComps;
  1151. % Detect & update status:
  1152. handles = DetectStatus(handles, g, s, c);
  1153. handles = UpdateStatusSettings(handles);
  1154. % Save handles:
  1155. guidata(hObject, handles);
  1156. %--- Executes on button press in ButtonRmvCompCleanData. ---%
  1157. %-----------------------------------------------------------%
  1158. function ButtonRmvCompCleanData_Callback(hObject, eventdata, handles)
  1159. if isempty(handles.name.DataID)
  1160. msgbox('Warning: Load DataID first.', 'Warning:');
  1161. return;
  1162. end
  1163. if isempty(handles.name.GroupID)
  1164. msgbox('Error: No GroupIDs specified.', 'Error:');
  1165. return;
  1166. end
  1167. if isempty(handles.name.SubjID)
  1168. msgbox('Error: No SubjIDs specified.', 'Error:');
  1169. return;
  1170. else
  1171. for g = 1:length(handles.name.GroupID)
  1172. if isempty(handles.name.SubjID{g})
  1173. msgbox('Error: Not all Groups have SubjIDs added.', 'Error:')
  1174. return;
  1175. end
  1176. end
  1177. end
  1178. if isempty(handles.name.CondID)
  1179. msgbox('Error: No CondIDs specified.', 'Error:');
  1180. return;
  1181. end
  1182. % Load required parameters:
  1183. InputParams.name = handles.name;
  1184. InputParams.paths.InputPreprocMEG = handles.paths.InputPreprocMEG;
  1185. InputParams.paths.ICAunmixing = handles.paths.ICAunmixing;
  1186. InputParams.paths.ICAcleanData = handles.paths.ICAcleanData;
  1187. InputParams.RejectComps = handles.gui.SelectComps;
  1188. % Check if unmixing info generated for each dataset:
  1189. % Check if components selected for each dataset:
  1190. MissingUnmixing = 0;
  1191. MissingSelection = 0;
  1192. for g = 1:length(handles.name.GroupID)
  1193. for s = 1:length(handles.name.SubjID{g})
  1194. for c = 1:length(handles.name.CondID)
  1195. if ~exist(handles.paths.ICAunmixing{g}{s,c}, 'file')
  1196. MissingUnmixing = 1;
  1197. end
  1198. if isempty(handles.gui.SelectComps{g}{s,c})
  1199. MissingSelection = 1;
  1200. end
  1201. end
  1202. end
  1203. end
  1204. if MissingUnmixing == 1
  1205. message = {'ERROR:'; '';
  1206. 'ICA unmixing info is missing for some of the selected datasets.';
  1207. 'Run ICA to generate the required files for these datasets.'};
  1208. msgbox(message, 'ERROR:')
  1209. return;
  1210. end
  1211. if MissingSelection == 1
  1212. prompt = {'WARNING:'; '';
  1213. 'Some of the input datasets do NOT have components selected for removal.';
  1214. 'Are you sure you wish to leave these datasets UNALTERED?'; '';
  1215. 'IMPORTANT: If you continue, components will NOT be removed from';
  1216. 'the datasets in question. They will simply be copied into the output';
  1217. 'DataID-ICAclean folder.'};
  1218. ContChoice = questdlg(prompt, 'WARNING:', 'CONTINUE', 'CANCEL', 'CANCEL');
  1219. if strcmp(ContChoice, 'CANCEL')
  1220. return;
  1221. end
  1222. end
  1223. CheckOpenPCT
  1224. % Reject components and reconstruct data:
  1225. disp('REJECTING COMPONENTS & RECONSTRUCTING DATA:')
  1226. MEGpipeline_RemoveICAcomps(InputParams);
  1227. % Detect & update status:
  1228. for g = 1:length(handles.name.GroupID)
  1229. StatusWaitbar = waitbar(0, ['Please wait. Scanning status for: ', ...
  1230. handles.name.GroupID{g}], 'Windowstyle', 'modal');
  1231. for s = 1:length(handles.name.SubjID{g})
  1232. waitbar(s/length(handles.name.SubjID{g}), StatusWaitbar);
  1233. for c = 1:length(handles.name.CondID)
  1234. handles = DetectStatus(handles, g, s, c);
  1235. end
  1236. end
  1237. delete(StatusWaitbar)
  1238. end
  1239. handles = UpdateStatusSettings(handles);
  1240. % Make copy of PreprocSettings .mat in new DataID folder:
  1241. PathOrigDataID = handles.paths.DataID;
  1242. PathCleanDataID = [handles.paths.Rootpath,'/DataID-ICAclean_',handles.name.DataID];
  1243. OldSettingsFile = [PathOrigDataID,'/PreprocSettings.mat'];
  1244. NewSettingsFile = [PathCleanDataID,'/PreprocSettings.mat'];
  1245. if exist(OldSettingsFile, 'file')
  1246. if exist(NewSettingsFile, 'file')
  1247. delete(NewSettingsFile);
  1248. end
  1249. CopyStatus = copyfile(OldSettingsFile, NewSettingsFile, 'f');
  1250. if CopyStatus == 0
  1251. msgbox('Warning: Failed to copy PreprocSettings.mat to new DataID-ICAclean folder.')
  1252. end
  1253. end
  1254. % Make copy of PreprocInputMEG .mat files in new DataID folder:
  1255. CopyFailed = 0;
  1256. for g = 1:length(handles.name.GroupID)
  1257. GroupPath = [handles.paths.DataID,'/GroupID_',handles.name.GroupID{g}];
  1258. InputMats = dir([GroupPath,'/PreprocInputMEG_*.mat']); % Find InputMats for group
  1259. InputMats = {InputMats.name};
  1260. for m = 1:length(InputMats)
  1261. OldMatFile = [PathOrigDataID,'/GroupID_',handles.name.GroupID{g},'/',InputMats{m}];
  1262. NewMatFile = [PathCleanDataID,'/GroupID_',handles.name.GroupID{g},'/',InputMats{m}];
  1263. if exist(NewMatFile, 'file')
  1264. delete(NewMatFile);
  1265. end
  1266. CopyStatus = copyfile(OldMatFile, NewMatFile, 'f');
  1267. if CopyStatus == 0
  1268. CopyFailed = 1;
  1269. end
  1270. end
  1271. end
  1272. if CopyFailed == 1
  1273. msgbox('Warning: Failed to copy PreprocInputMEG .mat(s) to new DataID-ICAclean folder.')
  1274. end
  1275. % Ask user if they wish to remove component files:
  1276. ButtonDeleteCompFiles_Callback(hObject, eventdata, handles);
  1277. % Save handles:
  1278. guidata(hObject, handles);
  1279. % Remove ErrorLog if empty:
  1280. if exist([pwd,'/ErrorLog_ICAcleaner.txt'], 'file')
  1281. LogCheck = dir('ErrorLog_ICAcleaner.txt');
  1282. if LogCheck.bytes == 0
  1283. delete('ErrorLog_ICAcleaner.txt');
  1284. end
  1285. end
  1286. %--- Executes on button press in ButtonDeleteCompFiles. ---%
  1287. %----------------------------------------------------------%
  1288. function ButtonDeleteCompFiles_Callback(hObject, eventdata, handles)
  1289. if isempty(handles.name.DataID)
  1290. msgbox('Warning: Load DataID first.', 'Warning:');
  1291. return;
  1292. end
  1293. if isempty(handles.name.GroupID)
  1294. msgbox('Error: No GroupIDs specified.', 'Error:');
  1295. return;
  1296. end
  1297. if isempty(handles.name.SubjID)
  1298. msgbox('Error: No SubjIDs specified.', 'Error:');
  1299. return;
  1300. else
  1301. for g = 1:length(handles.name.GroupID)
  1302. if isempty(handles.name.SubjID{g})
  1303. msgbox('Error: Not all Groups have SubjIDs added.', 'Error:')
  1304. return;
  1305. end
  1306. end
  1307. end
  1308. if isempty(handles.name.CondID)
  1309. msgbox('Error: No CondIDs specified.', 'Error:');
  1310. return;
  1311. end
  1312. % Confirm removal:
  1313. prompt = {'RECOMMENDED:'; '';
  1314. 'To save space, ICA component files can be removed after ICA cleaning.';
  1315. 'Do you wish to remove these large component files?'; '';
  1316. 'NOTE: Unmixing info from the ICA decompositions will be kept.';
  1317. 'These will allow you to quickly create component files again if needed.'};
  1318. RmvCompFiles = questdlg(prompt, 'RECOMMENDED:', 'YES', 'NO', 'YES');
  1319. if strcmp(RmvCompFiles, 'NO')
  1320. return;
  1321. end
  1322. % Check if ICAcleanData exists for all datasets:
  1323. UnfinishedCleaning = 0;
  1324. for g = 1:length(handles.name.GroupID)
  1325. for s = 1:length(handles.name.SubjID{g})
  1326. for c = 1:length(handles.name.CondID)
  1327. ICAcomponents = handles.paths.ICAcomponents{g}{s,c};
  1328. ICAcleanData = handles.paths.ICAcleanData{g}{s,c};
  1329. if exist(ICAcomponents, 'file') && ~exist(ICAcleanData, 'file')
  1330. UnfinishedCleaning = 1;
  1331. end
  1332. end
  1333. end
  1334. end
  1335. if UnfinishedCleaning == 1
  1336. prompt = {'WARNING:'; '';
  1337. 'Some of the selected datasets have NOT been ICA cleaned yet.';
  1338. 'Are you sure you wish to remove component files?'};
  1339. ContinueRmv = questdlg(prompt, 'WARNING:', 'YES', 'NO', 'NO');
  1340. if strcmp(ContinueRmv, 'NO')
  1341. return;
  1342. end
  1343. end
  1344. % Remove component files:
  1345. for g = 1:length(handles.name.GroupID)
  1346. for s = 1:length(handles.name.SubjID{g})
  1347. for c = 1:length(handles.name.CondID)
  1348. if exist(handles.paths.ICAcomponents{g}{s,c}, 'file')
  1349. delete(handles.paths.ICAcomponents{g}{s,c});
  1350. end
  1351. end
  1352. end
  1353. end
  1354. %=================================%
  1355. % FUNCTION TO OPEN MODAL WAITBOX: %
  1356. %=================================%
  1357. function WaitBox = StartWaitBox(TextString)
  1358. WaitBox = dialog('Units', 'pixels', 'Position', [500 500 300 40],...
  1359. 'Windowstyle', 'modal', 'NextPlot', 'new', 'Name', 'Please Wait:');
  1360. uicontrol('Parent', WaitBox, 'Units', 'pixels', 'Position', [20 10 250 20],...
  1361. 'Style', 'text', 'String', TextString, 'FontWeight', 'bold');
  1362. movegui(WaitBox, 'center');
  1363. %============================%
  1364. % GUIDE CREATEFCN FUNCTIONS: %
  1365. %============================%
  1366. % --- Executes during object creation, after setting all properties.
  1367. function TextboxRootpath_CreateFcn(hObject, eventdata, handles)
  1368. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1369. set(hObject,'BackgroundColor','white');
  1370. end
  1371. % --- Executes during object creation, after setting all properties.
  1372. function TextboxDataID_CreateFcn(hObject, eventdata, handles)
  1373. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1374. set(hObject,'BackgroundColor','white');
  1375. end
  1376. % --- Executes during object creation, after setting all properties.
  1377. function ListboxGroupID_CreateFcn(hObject, eventdata, handles)
  1378. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1379. set(hObject,'BackgroundColor','white');
  1380. end
  1381. % --- Executes during object creation, after setting all properties.
  1382. function ListboxSubjID_CreateFcn(hObject, eventdata, handles)
  1383. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1384. set(hObject,'BackgroundColor','white');
  1385. end
  1386. % --- Executes during object creation, after setting all properties.
  1387. function TextboxSubjID_CreateFcn(hObject, eventdata, handles)
  1388. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1389. set(hObject,'BackgroundColor','white');
  1390. end
  1391. % --- Executes during object creation, after setting all properties.
  1392. function ListboxCondID_CreateFcn(hObject, eventdata, handles)
  1393. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1394. set(hObject,'BackgroundColor','white');
  1395. end
  1396. % --- Executes during object creation, after setting all properties.
  1397. function TextboxCondID_CreateFcn(hObject, eventdata, handles)
  1398. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1399. set(hObject,'BackgroundColor','white');
  1400. end
  1401. % --- Executes during object creation, after setting all properties.
  1402. function ListboxInpOutStatus_CreateFcn(hObject, eventdata, handles)
  1403. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1404. set(hObject,'BackgroundColor','white');
  1405. end
  1406. % --- Executes during object creation, after setting all properties.
  1407. function ListboxRmvCompStatus_CreateFcn(hObject, eventdata, handles)
  1408. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
  1409. set(hObject,'BackgroundColor','white');
  1410. end